#![feature(char_min)]

use std::io;

fn main() {
    println!("Hello, world!");

    // 定义变量，默认不可变
    let immutable_var = 100;

    println!("immutable_var: {immutable_var}");

    //immutable_var = 200;

    // 定义可变变量
    let mut mutable_var = 100;
    println!("mutable_var: {mutable_var}");
    mutable_var = 200;
    println!("mutable_var: {mutable_var}");

    // 基础数据类型
    let _var_i8_min: i8 = i8::MIN;
    let _var_i8_max: i8 = i8::MAX;
    let _var_i16_min: i16 = i16::MIN;
    let _var_i16_max: i16 = i16::MAX;
    let _var_i32_min: i32 = i32::MIN;
    let _var_i32_max: i32 = i32::MAX;
    let _var_i64_min: i64 = i64::MIN;
    let _var_i64_max: i64 = i64::MAX;
    let _var_i128_min: i128 = i128::MIN;
    let _var_i128_max: i128 = i128::MAX;
    let _var_u8_min: u8 = u8::MAX;
    let _var_u8_max: u8 = u8::MAX;
    let _var_u16_min: u16 = u16::MIN;
    let _var_u16_max: u16 = u16::MAX;
    let _var_u32_min: u32 = u32::MIN;
    let _var_u32_max: u32 = u32::MAX;
    let _var_u64_min: u64 = u64::MIN;
    let _var_u64_max: u64 = u64::MAX;
    let _var_u128_min: u128 = u128::MIN;
    let _var_u128_max: u128 = u128::MAX;

    // isize/usize 大小和机器字长相关，32机器4字节，64为机器8字节
    let _var_isize_min: isize = isize::MIN;
    let _var_isize_max: isize = isize::MAX;
    let _var_usize_min: usize = usize::MIN;
    let _var_usize_max: usize = usize::MAX;

    // bool: true / false
    let _var_bool: bool = true;

     // char: Unicode 字符，4个字节，'\u{0}' ~ '\u{10FFFF}'
    let _var_char_min: char = char::MIN;
    let _var_char_max: char = char::MAX;

    let _var_f32_min: f32 = f32::MIN;
    let _var_f32_max: f32 = f32::MAX;

    let _var_f64_min: f64 = f64::MIN;
    let _var_f64_max: f64 = f64::MAX;

    // 打印所有变量的值
    println!("i8 range: {} ~ {}", _var_i8_min, _var_i8_max);
    println!("i16 range: {} ~ {}", _var_i16_min, _var_i16_max);
    println!("i32 range: {} ~ {}", _var_i32_min, _var_i32_max);
    println!("i64 range: {} ~ {}", _var_i64_min, _var_i64_max);
    println!("i128 range: {} ~ {}", _var_i128_min, _var_i128_max);
    println!("u8 range: {} ~ {}", _var_u8_min, _var_u8_max);
    println!("u16 range: {} ~ {}", _var_u16_min, _var_u16_max);
    println!("u32 range: {} ~ {}", _var_u32_min, _var_u32_max);
    println!("u64 range: {} ~ {}", _var_u64_min, _var_u64_max);
    println!("u128 range: {} ~ {}", _var_u128_min, _var_u128_max);
    println!("isize range: {} ~ {}", _var_isize_min, _var_isize_max);
    println!("usize range: {} ~ {}", _var_usize_min, _var_usize_max);
    println!("bool value: {}", _var_bool);
    println!("char range: {} (\\u{{0}}) ~ {} (\\u{{10FFFF}})", _var_char_min as u32, _var_char_max as u32);

    println!("f32 range: {} ~ {}", _var_f32_min, _var_f32_max);
    println!("f64 range: {} ~ {}", _var_f64_min, _var_f64_max);

    // 变量遮蔽(shadowing)
    let var = 100;
    println!("var: {var}");
    let var = "Hello world!";
    println!("var: {var}");

    // 定义常量
    const MATH_PI: f64 = 3.14159;
    const SECONDS_PER_HOUR: i32 = 1 * 60 * 60;

    // 复合类型：元组
    // 元组是一个将多个不同类型的值组合进一个复合类型的主要方式。元组长度固定：一旦声明，其长度不会增大或缩小。
    let var_tuple: (bool, i32, f64) = (false, 100, 1.0);

    // 为了从元组中获取单个值，可以使用模式匹配（pattern matching）来解构（destructure）元组值
    let (x, y, z) = var_tuple;

    // 元组的访问
    println!("one={}, two={}, three={}", var_tuple.0, var_tuple.1, var_tuple.2);


    // 复合类型：数组
    // 和元组类型相比，数组中的每个元素的类型必须相同
    let var_array = [1,2,3,4,5];
    let var_array = ["one", "two", "three"];
    let var_array:[u32;6] = [1, 2, 3, 4, 5, 6];

    println!("one={}, two={}, three={}", var_array[0], var_array[1], var_array[2]);

    // 数组越界访问

    let mut index = String::new();

    io::stdin()
       .read_line(&mut index)
       .expect("Failed to read line");

    let index : usize = index.trim()
                             .parse()
                             .expect("Index entered was not a number");
    let element = var_array[index];

    println!("The value of the element at index {index} is: {element}");
}
